page.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import '@/app/styles/community.scss';
  2. import { Target, Flame, Trophy, ListChecks } from 'lucide-react';
  3. import { fetchTrackRecord } from '@/lib/api/community';
  4. import TierBadge from '@/components/community/TierBadge';
  5. type Props = {
  6. params: Promise<{ sid: string }>;
  7. };
  8. // 프로필 "예측 적중률" 탭 (익명 허용 · SSR) — 티어 배지·적중률·스트릭·표본수
  9. export default async function UserProfileTrackRecordPage({ params }: Props)
  10. {
  11. const { sid } = await params;
  12. const res = await fetchTrackRecord(sid);
  13. const record = res.success ? res.data : null;
  14. if (!res.success) {
  15. return <div className='track-leaderboard__error' role='alert'>예측 적중률을 불러오지 못했습니다.</div>;
  16. }
  17. if (!record || !record.hasRecord) {
  18. return <div className='user-profile__empty'>아직 채점된 예측이 없습니다.</div>;
  19. }
  20. return (
  21. <>
  22. <div className='track-summary'>
  23. <span className='track-summary__label'>등급</span>
  24. <TierBadge tierCode={record.tierCode} label={record.tier} />
  25. </div>
  26. <section className='user-profile__stats' aria-label='예측 적중률'>
  27. <div className='user-profile__stat'>
  28. <Target size={20} className='user-profile__stat-icon' strokeWidth={1.75} />
  29. <div className='user-profile__stat-body'>
  30. <span className='user-profile__stat-label'>적중률</span>
  31. <span className='user-profile__stat-value'>{record.hitRate.toFixed(1)}%</span>
  32. </div>
  33. </div>
  34. <div className='user-profile__stat'>
  35. <ListChecks size={20} className='user-profile__stat-icon' strokeWidth={1.75} />
  36. <div className='user-profile__stat-body'>
  37. <span className='user-profile__stat-label'>채점 예측 (적중/실패/무효)</span>
  38. <span className='user-profile__stat-value'>{record.hits} / {record.misses} / {record.voids}</span>
  39. </div>
  40. </div>
  41. <div className='user-profile__stat'>
  42. <Flame size={20} className='user-profile__stat-icon' strokeWidth={1.75} />
  43. <div className='user-profile__stat-body'>
  44. <span className='user-profile__stat-label'>현재 연속 적중</span>
  45. <span className='user-profile__stat-value'>{record.currentStreak.toLocaleString()}</span>
  46. </div>
  47. </div>
  48. <div className='user-profile__stat'>
  49. <Trophy size={20} className='user-profile__stat-icon' strokeWidth={1.75} />
  50. <div className='user-profile__stat-body'>
  51. <span className='user-profile__stat-label'>최고 연속 적중</span>
  52. <span className='user-profile__stat-value'>{record.bestStreak.toLocaleString()}</span>
  53. </div>
  54. </div>
  55. </section>
  56. </>
  57. );
  58. }